/*
  设备类型：挂锁
*/

let deviceId = ''
let serviceId = ''
let characteristicId = ''
let servicweId = '0000CCD0-0000-1000-8000-00805F9B34FB' //同时具有可读、可写、通知三种属性的UUID
let notifyCharacteristicsId = '' //通知特征值UUID
let writeCharacteristicsId = "0000CCD2-0000-1000-8000-00805F9B34FB" ////可写特征值uuid
let readCharacteristicsId = "0000CCD1-0000-1000-8000-00805F9B34FB"
let totalLength = 0
let key = "2B7E1516010101010101010101010101" //加密key
let nonce = ""
// let hander = "6c696e6b706f7765723836323331" //加密头
let hander = "61697061646c6f636b3836323331" //加密头
let ccmEncryptHexStr = "" //开锁加密后的指令
let setEncryptHexStr = '' //设置开锁密码指令
let lockSn = ''
let newlockSn = ''
let lockFW = ''
let lockHW = ''
let lockVerion = ''
let mac = ''
let randomVal = ''
let jieshoudao = ''
let isFirstReadNum = 0
let hwVersion = ''
let fwVersion = ''
let count = 0
let counts = 0
let newPsw = ''
let electric = ''
let finishFlag = false
let that_page = null
let open = true //是否是关锁操作
const app = getApp();
const aes = require("./aes.js");
var blueApi= {
  //第一步  蓝牙初始化
  async openBluetoothAdapter(that,openFlag) {
    open = openFlag
    console.log('是否开锁：'+open);
    that_page = that
    const _this = this
    wx.showLoading({
      title: '初始化中...',
    })
    //初始化值
    count = 0
    counts=0
    finishFlag = false
    ccmEncryptHexStr = ''
    setEncryptHexStr = ''
    //先释放
    wx.closeBluetoothAdapter({
      complete(){
        //再连接
        wx.openBluetoothAdapter({
          success (res) {
            console.log('初始化蓝牙成功')
            wx.hideLoading({
              success: (res) => {},
            })
            _this.getBluetoothAdapterState()
          },
          fail: err => {
            wx.hideLoading({
              success: (res) => {},
            })
            console.log(err,'openBluetoothAdapter失败')
          }
        })
      }
    })
  },
  //第二步
  getBluetoothAdapterState() {
    var _this = this
    wx.getBluetoothAdapterState({
      success: res => {
        console.log(res);
        if (res.available == false) {
          _this.showModal("设备无法开启蓝牙连接")
          wx.closeBluetoothAdapter()
        } else if (res.available) {
          _this.startBluetoothDevicesDiscovery() // 蓝牙适配器正常，去执行搜索外围设备
          console.log("开启搜索外围设备")
        }
      }
    })
  },
  //第三步
  startBluetoothDevicesDiscovery() {
    var _this = this
    wx.startBluetoothDevicesDiscovery({
      powerLevel:'high',
      services: ['CCD0'],
      allowDuplicatesKey: false,
      success: res => {
        console.log("第三步所有蓝牙设备", res)
        if (!res.isDiscovering) { // 是否在搜索设备
          _this.getBluetoothAdapterState()
        } else {
          _this.onBluetoothDeviceFound() // 搜索成功后，执行监听设备的api
        }
      },
      fail: err => {
        console.log("蓝牙搜寻失败")
        wx.stopBluetoothDevicesDiscovery() // 没有搜索到设备
        wx.closeBluetoothAdapter() // 关闭蓝牙模块
      }
    })
  },
  //第四步  搜索成功后，执行监听设备的api
  onBluetoothDeviceFound() {
    var _this = this
    wx.showLoading({
      title: '请唤醒锁...',
    })
    wx.onBluetoothDeviceFound(res => {
      console.log("第四步所有新蓝牙设备", res)
      let hasDe = false
      var advertisData
      for (let i = 0; i < res.devices.length; i++) {
        deviceId = res.devices[i].deviceId
        //后台绑定设备mac地址
        let Mac = app.globalData.deviceId.toUpperCase()
        if (_this.getPlatform() == 'android') {
          console.log("安卓设备")
          advertisData = _this.ab2hex(res.devices[i].advertisData)
          if (Mac == deviceId) {
            hasDe = true
            wx.hideLoading({
              success: (res) => {},
            })
            console.log("设备id", deviceId)
            break
          }
        } else if (_this.getPlatform() == 'ios') {
          console.log("ios设备")
          advertisData = _this.ab2hex(res.devices[i].advertisData)
          mac = advertisData.slice(18, 30)
          mac = mac.toUpperCase()
          mac = _this.str2mac(mac)
          console.log(mac)
          if (mac == Mac) {
            hasDe = true
            wx.hideLoading({
              success: (res) => {},
            })
            console.log("设备id", deviceId)
            break
          }
        }
      }
      if (hasDe) {
        randomVal = advertisData.substring(0, 8);
        lockSn = advertisData.substring(8, 12);
        hwVersion = advertisData.substring(12, 14);
        fwVersion = advertisData.substring(14, 18);
        lockVerion = "Hw：" + hwVersion + " Fw:" + fwVersion,
        mac = advertisData.slice(18, 30)
        console.log("广播数据", advertisData)
        //加密开始
        //获取到key信息后  进行nonce获取操作
        var mic = "000000000000000000000000";
        mic = randomVal + mic;
        console.log("广播数据截取:" + randomVal + "mic:" + mic)
        var ecbEncVal = aes.bytes_to_hex(_this.ecbEncryPt(aes, mic, key));
        console.log(ecbEncVal)
        if (ecbEncVal) {
          if (ecbEncVal.length != 32) {
            //不是16字节的数据
            return null;
          } else {
            //a99881fe0000560601402e7174f2b600000000000000
            //数据的截取拼接
            var num1 = ecbEncVal.substring(16, 18);
            var num2 = ecbEncVal.substring(14, 16);
            var num3 = ecbEncVal.substring(22, 24);
            var num4 = ecbEncVal.substring(10, 12);
            var num5 = ecbEncVal.substring(4, 6);
            var num6 = ecbEncVal.substring(20, 22);
            var num7 = ecbEncVal.substring(8, 10);
            var num8 = ecbEncVal.substring(28, 30);
            var num9 = ecbEncVal.substring(0, 2);
            var num10 = ecbEncVal.substring(12, 14);
            var num11 = ecbEncVal.substring(26, 28);
            var num12 = ecbEncVal.substring(18, 20);
            nonce = num1 + num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9 + num10 + num11 + num12;
          }
        } else {
          //不存在加密的信息传入时，返回 null
          console.log("不存在加密的信息传入时，返回 null");
          return null;
        }
        //开锁没加密前的命令

        //开锁
          //var openlockkey = app.globalData.openlockkey
        // let openlockkey='08080606'
        // var openlockContent = "016E04" + openlockkey + "000000000000000000";

        //设置密码
        // var setlockkey="42686634"+lockSn+"28719545"
        // var openlockContent="016F04"+setlockkey+"000000"

        //初始化锁
        // var setlockkey="08080606"+lockSn
        // var openlockContent="017906"+setlockkey+"00000000000000"

        // var ccmEncryptVal = _this.ccmEncryPt(aes, hander, openlockContent, key, nonce);
        // console.log("开锁密钥加密后的结果：" + aes.bytes_to_hex(ccmEncryptVal));
        // ccmEncryptHexStr = aes.bytes_to_hex(ccmEncryptVal);

        wx.stopBluetoothDevicesDiscovery() // 匹配到设备后关闭搜索
        _this.createBLEConnection() // 连接蓝牙
      }
    })
  },
  //第五步
  createBLEConnection() { // 连接低功耗蓝牙
    var _this = this
    wx.showLoading({
      title: '连接中...',
    })
    wx.createBLEConnection({
      deviceId: deviceId,
      success: res => {
        _this.getBLEDeviceServices()
        wx.hideLoading({
          success: (res) => {},
        })
        wx.showToast({
          title: '连接成功',
          icon: 'none',
          duration: 3000
        })
        console.log("蓝牙设备已连接")
      },
      fail: err => {
        console.log("连接失败", err)
        wx.hideLoading({
          success: (res) => {},
        })
        _this.showModal("连接失败,请重试")
        wx.closeBluetoothAdapter() // 连接失败关闭蓝牙模块
      }
    })
  },
  //第六步
  getBLEDeviceServices() {
    var _this = this
    wx.getBLEDeviceServices({
      deviceId: deviceId,
      success: res => {
        console.log("蓝牙服务数据", res)
        for (let i = 0; i < res.services.length; i++) {
          // 如果提前得知可以直接判断，如果不知道可以用蓝牙工具看一下服务所需的功能
          if (res.services[i].uuid == servicweId) {
            serviceId = res.services[i].uuid
            console.log("蓝牙服务id", res.services[i].uuid)
            _this.getBLEDeviceCharacteristics()
          }
        }
      },
      fail: err => {
        console.log("获取服务失败")
        wx.closeBluetoothAdapter() // 关闭蓝牙模块
      }
    })
  },

  //第七步
  getBLEDeviceCharacteristics() { // 获取服务中的特征值
    var _this = this
    wx.getBLEDeviceCharacteristics({
      deviceId: deviceId,
      serviceId: serviceId,
      success: res => {
        console.log("蓝牙服务特征值", res)
        readCharacteristicsId = "0000CCD1-0000-1000-8000-00805F9B34FB"
        writeCharacteristicsId = "0000CCD2-0000-1000-8000-00805F9B34FB"
        if(open){
          _this.openLock(app.globalData.openlockkey)
        }else{
          _this.closeLock(app.globalData.openlockkey)
        }
      },
      fail: err => {
        console.log("获取服务中的特征值失败")
        wx.closeBluetoothAdapter() // 关闭蓝牙模块
      }
    })
  },
  //开锁
  openLock(Psw) {
    count = 1
    let openlockkey = Psw
    var openlockContent = "016E04" + openlockkey + "000000000000000000";
    var ccmEncryptVal = this.ccmEncryPt(aes, hander, openlockContent, key, nonce);
    ccmEncryptHexStr = aes.bytes_to_hex(ccmEncryptVal);
    this.onBLECharacteristicValueChange()
    this.writeBLECharacteristicValue(ccmEncryptHexStr, 0)
    wx.showLoading({
      title: '开锁中',
    })
  },
  //关锁
  closeLock(Psw) {
    count = 1
    let openlockkey = Psw
    var openlockContent = "016304" + openlockkey + "000000000000000000";
    var ccmEncryptVal = this.ccmEncryPt(aes, hander, openlockContent, key, nonce);
    ccmEncryptHexStr = aes.bytes_to_hex(ccmEncryptVal);
    this.onBLECharacteristicValueChange()
    this.writeBLECharacteristicValue(ccmEncryptHexStr, 0)
    wx.showLoading({
      title: '关锁中',
    })
  },

  // 向蓝牙设备写入数据
  writeBLECharacteristicValue(value, index1) {
    var _this = this
    //开始分包
    let dataArray = _this.datasubpck(value)
    totalLength = dataArray.length
    let subhex = dataArray[index1]
    var temp = subhex;
    var prefix = '0x'
    var affix = ','
    var temp2 = ''
    for (var i = 0; i < temp.length / 2; i++) {
      if (i < (temp.length / 2 - 1)) {
        temp2 = temp2 + prefix + temp.substring(i * 2, i * 2 + 2) + affix
      } else {
        temp2 = temp2 + prefix + temp.substring(i * 2)
      }
    }
    var buffer1 = new ArrayBuffer(subhex.length / 2) //字节长度 一个字节两个字符所以除以2
    var dataView1 = new DataView(buffer1)
    var str1 = temp2;
    var arr1 = str1.split(',')
    var val;
    for (var i = 0; i < arr1.length; i++) {
      val = parseInt(arr1[i], 16)
      dataView1.setInt8(i, val);
    }
    index1 = index1 + 1
    var typedArray = new Uint8Array(subhex.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    console.log(typedArray)
    console.log("发送的指令===" + _this.ab2hex(buffer1))
    wx.writeBLECharacteristicValue({
      deviceId: deviceId,
      serviceId: servicweId,
      characteristicId: writeCharacteristicsId,
      value: buffer1, // 这个输入的指令，需要转换成ArrayBuffer
      success: res => {
        console.log(res, "写入成功"+count)
        if(finishFlag){
          _this.destory()
          wx.hideLoading({
            success: (res) => {},
          })
          that_page.setData({
            lock: false
          })
          that_page.report(open)
        }else{
          setTimeout(() => {
            _this.readBLECharacteristicValue()
          }, 500)
        }
      },
      fail: err => {
        _this.destory()
        _this.showModal("开锁失败，请重试")
        wx.hideLoading({
          success: (res) => {},
        })
      }
    })
  },
  //读开锁命令
  readBLECharacteristicValue() {
    wx.readBLECharacteristicValue({
      deviceId: deviceId,
      serviceId: "0000CCD0-0000-1000-8000-00805F9B34FB",
      characteristicId: "0000CCD1-0000-1000-8000-00805F9B34FB",
      success: function (res) {
        console.log("蓝牙返回数据readBLECharacteristicValue", res)
      },
      fail: function (res) {

      }
    })
  },
  onBLECharacteristicValueChange() {
    let _this = this
    wx.onBLECharacteristicValueChange(function (res) {
      console.log("蓝牙返回数据onBLECharacteristicValueChange", res)
      let receData = _this.ab2hex(res.value)
      var decryptVal = _this.ccmDectyPt(aes, hander, receData, key, nonce)
      var decryptHexVal = aes.bytes_to_hex(decryptVal);
      //电量
      electric = decryptHexVal.slice(8, 10)
      electric = _this.hex2int(electric)
      that_page.setData({
        electric
      })
      console.log("电量", electric)
      if (count == 1) {
          console.log("开锁成功")
          //随机八位数新密码
          newPsw = parseInt(Math.random() * 100000000) + ''
          newPsw = newPsw.padStart(8, "0")
          console.log("新密码", newPsw)
          //随机四位数sn
          newlockSn = parseInt(Math.random() * 10000) + ''
          newlockSn = newlockSn.padStart(4, "0")
          //设置新密码
          _this.setPassword(newPsw, newlockSn)
          finishFlag = false
      } else if (count == 2) {
        //sn
        let snState = decryptHexVal.slice(16, 20)
        console.log(snState, newlockSn)
        if (parseInt(snState) == parseInt(newlockSn)) { //密码修改成功
          console.log("修改密码成功")
          //取消监听蓝牙连接状态
          wx.offBLEConnectionStateChange()
          electric=parseInt(electric)
          finishFlag = true
          if(open){
            _this.openLock(newPsw)
          }else{
            _this.closeLock(newPsw)
          }
        } else { //密码修改失败
          console.log("修改密码失败")
          _this.showModal("开锁失败,请重试")
          wx.hideLoading({
            success: (res) => {},
          })
          _this.destory()
        }
      }
    })
  },
  //设置密码
  setPassword(newPsw, newlockSn) {
    count = 2
    console.log(newPsw, newlockSn)
    newPsw = String(newPsw)
    newlockSn = String(newlockSn)
    var setlockkey = newPsw + newlockSn + app.globalData.openlockkey
    console.log(setlockkey, "setlockkey")
    var openlockContent = "016F0A" + setlockkey + "000000"
    var ccmEncryptVal = this.ccmEncryPt(aes, hander, openlockContent, key, nonce);
    console.log("开锁密钥加密后的结果：" + aes.bytes_to_hex(ccmEncryptVal));
    setEncryptHexStr = aes.bytes_to_hex(ccmEncryptVal);
    this.writeBLECharacteristicValue(setEncryptHexStr, 0)
  },
  destory() {
    wx.closeBLEConnection({deviceId:deviceId})
    wx.closeBluetoothAdapter()
  },
  




  //---------------------------------------------------------
  //ECB加密
  ecbEncryPt(aes, contentVal, keyVal) {
    const content = aes.hex_to_bytes(contentVal);
    const keys = aes.hex_to_bytes(keyVal);
    return aes.AES_ECB.encrypt(content, keys);
  },
  //CCM加密
  ccmEncryPt(aes, hander, contentVal, keyVal, nonceVal) {
    var hander = aes.hex_to_bytes(hander);
    const content = aes.hex_to_bytes(contentVal);
    const keys = aes.hex_to_bytes(keyVal);
    const nonce = aes.hex_to_bytes(nonceVal);
    return aes.AES_CCM.encrypt(content, keys, nonce, hander, 4)
  },
  //CCM解密
  ccmDectyPt(aes, hander, contentVal, keyVal, nonceVal) {
    console.log(hander)
    var hander = aes.hex_to_bytes(hander);
    const content = aes.hex_to_bytes(contentVal);
    console.log("content-> " + aes.bytes_to_hex(content));
    const keys = aes.hex_to_bytes(keyVal);
    console.log("keys-> " + aes.bytes_to_hex(keys));
    const nonce = aes.hex_to_bytes(nonceVal);
    console.log("nonce-> " + aes.bytes_to_hex(nonce));
    try {
      return aes.AES_CCM.decrypt(content, keys, nonce, hander, 4);
    } catch (err) {
      console.log("解密异常：" + err);
      return null;
    }
  },
  //判断操作系统类型
  getPlatform() {
    let platform = ''
    wx.getSystemInfo({
      success: (res) => {
        // console.log(res)
        if (res.system.indexOf('iOS') > -1) {
          platform = 'ios'
        } else if (res.system.indexOf('Android') > -1) {
          platform = 'android'
        } else {
          platform = 'pc'
        }
      }
    })
    return platform
  },
  //定义版本比较；Android 从微信 6.5.7 开始支持，iOS 从微信 6.5.6 开始支持
  versionCompare(ver1, ver2) {
    var version1pre = parseFloat(ver1)
    var version2pre = parseFloat(ver2)
    var version1next = parseInt(ver1.replace(version1pre + ".", ""))
    var version2next = parseInt(ver2.replace(version2pre + ".", ""))
    if (version1pre > version2pre)
      return true
    else if (version1pre < version2pre)
      return false
    else {
      if (version1next > version2next)
        return true
      else
        return false
    }
  },
  //获取系统当前版本
  getVersion() {
    let version = ''
    wx.getSystemInfo({
      success: (res) => {
        let system = res.system
        if (this.getPlatform() == 'android') {
          version = system.replace("Android", "").replace(" ", "")
        } else if (this.getPlatform() == 'ios') {
          version = system.replace("iOS", "").replace(" ", "")
        }
      }
    })
    return version
  },
  //位置信息授权
  userLocation(successFun, failFun) {
    wx.getSetting({
      success(res) {
        if (!res.authSetting['scope.userLocation']) {
          wx.authorize({
            scope: 'scope.userLocation',
            success: function () {
              successFun && successFun()
            },
            fail: function (res) {
              wx.hideLoading()
              wx.showModal({
                title: '提示',
                content: "小程序需要您的微信位置授权，是否重新授权？",
                showCancel: true,
                cancelText: "否",
                confirmText: "是",
                success: function (res2) {
                  if (res2.confirm) { //用户点击确定'
                    wx.openSetting({
                      success: (res3) => {
                        if (res3.authSetting['scope.userLocation']) {
                          //已授权
                          successFun && successFun()
                        } else {
                          failFun && failFun()
                        }
                      }
                    })
                  } else {
                    failFun && failFun()
                  }
                }
              });
            }
          })
        } else {
          successFun && successFun()
        }
      }
    })
  },
  //安卓系统开启手机定位
  isLocation() {
    let that = this
    if (that.getPlatform() == 'android') {
      that.userLocation(
        function success() {
          wx.showLoading({
            title: '获取定位中...',
          })
          wx.getLocation({
            type: 'wgs84',
            success(res) {
              wx.hideLoading({
                success: (res) => {},
              })
              console.log("成功")
              //蓝牙初始化
              that.openBluetoothAdapter()
            },
            fail() {
              console.log("失败")
              that.showModal('请打开手机定位后重试')
            }
          })
        },
        function fail() {

        }
      )
    } else {
      //蓝牙初始化
      that.openBluetoothAdapter()
    }
  },




 


  //关锁
  clockLock() {
    console.log('关锁')
    let openlockkey = app.globalData.openlockkey
    var openlockContent = "016304" + openlockkey + "000000000000000000";
    var ccmEncryptVal = this.ccmEncryPt(aes, hander, openlockContent, key, nonce);
    console.log("开锁密钥加密后的结果：" + aes.bytes_to_hex(ccmEncryptVal));
    ccmEncryptHexStr = aes.bytes_to_hex(ccmEncryptVal);
    this.writeBLECharacteristicValue(ccmEncryptHexStr, 0)
  },

  notifyBLECharacteristicValueChange() { // 启用蓝牙特征值变化时的notify功能
    var _this = this
    wx.notifyBLECharacteristicValueChange({
      deviceId: deviceId,
      serviceId: servicweId,
      characteristicId: writeCharacteristicsId,
      state: true,
      success: res => {
        console.log(res, 'notifyBLECharacteristicValueChange');
        _this.openLock(app.globalData.openlockkey)
      },
      fail: err => {
        console.log("启用BLE蓝牙特征值变化时的notify功能错误")
        wx.closeBluetoothAdapter() // 关闭蓝牙模块
      }
    })
  },


 


  //字符串转mac格式
  str2mac(str) {
    return str.replace(/\w(?=(\w{2})+$)/g, "$&:");
  },
  // ArrayBuffer转16进度字符串示例
  ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  },
  //16进制转10进制
  hex2int(hex) {
    var len = hex.length,
      a = new Array(len),
      code;
    for (var i = 0; i < len; i++) {
      code = hex.charCodeAt(i);
      if (48 <= code && code < 58) {
        code -= 48;
      } else {
        code = (code & 0xdf) - 65 + 10;
      }
      a[i] = code;
    }

    return a.reduce(function (acc, c) {
      acc = 16 * acc + c;
      return acc;
    }, 0);
  },
  //分包方法 linfanhe 20180524
  datasubpck(datahex) {
    var arrayObj = new Array();
    for (var i = 0; i < datahex.length; i += 40) {
      // 预加 最大包长度，如果依然小于总数据长度，可以取最大包数据大小
      if ((i + 40) < datahex.length) {
        arrayObj.push(datahex.substring(i, i + 40))

      } else {
        arrayObj.push(datahex.substring(i))
      }
    }
    return arrayObj;
  },
  //模态框
  showModal(content) {
    wx.showModal({
      title: '提示',
      content: content,
      success(res) {
        if (res.confirm) {
          console.log('用户点击确定')
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
    })
  }
}
module.exports=blueApi